bitkeeper revision 1.1589 (4299ca474xuIi4-NBh-bI0ilQ8Sw7w)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 29 May 2005 13:57:27 +0000 (13:57 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 29 May 2005 13:57:27 +0000 (13:57 +0000)
More bitop cleanups and code improvements.
Signed-off-by: Keir Fraser <keir@xensource.com>
.rootkeys
xen/arch/x86/bitops.c [new file with mode: 0644]
xen/include/asm-x86/bitops.h

index 16e1ca03ab7ca8f7a1aacad8668fe0608e5644af..9cb513b2427f415f37e73ea2707d503c7626e696 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3e5636e5FAYZ5_vQnmgwFJfSdmO5Mw xen/arch/x86/acpi/boot.c
 3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/x86/apic.c
 42360b3244-Q6BpEKhR_A1YtG1wPNQ xen/arch/x86/audit.c
+4299ca46lrYcJPWxWgB4KTNkRQ7CwQ xen/arch/x86/bitops.c
 3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/arch/x86/boot/mkelf32.c
 3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S
 40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
diff --git a/xen/arch/x86/bitops.c b/xen/arch/x86/bitops.c
new file mode 100644 (file)
index 0000000..64e7a31
--- /dev/null
@@ -0,0 +1,99 @@
+
+#include <xen/bitops.h>
+#include <xen/lib.h>
+
+unsigned long __find_first_bit(
+    const unsigned long *addr, unsigned long size)
+{
+    unsigned long d0, d1, res;
+
+    __asm__ __volatile__ (
+        "   xor %%eax,%%eax\n\t" /* also ensures ZF==1 if size==0 */
+        "   repe; scas"__OS"\n\t"
+        "   je 1f\n\t"
+        "   lea -"STR(BITS_PER_LONG/8)"(%2),%2\n\t"
+        "   bsf (%2),%0\n"
+        "1: sub %5,%2\n\t"
+        "   shl $3,%2\n\t"
+        "   add %2,%0"
+        : "=&a" (res), "=&c" (d0), "=&D" (d1)
+        : "1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG),
+          "2" (addr), "b" (addr) : "memory" );
+
+    return res;
+}
+
+unsigned long __find_next_bit(
+    const unsigned long *addr, unsigned long size, unsigned long offset)
+{
+    const unsigned long *p = addr + (offset / BITS_PER_LONG);
+    unsigned long set, bit = offset & (BITS_PER_LONG - 1);
+
+    ASSERT(offset < size);
+
+    if ( bit != 0 )
+    {
+        /* Look for a bit in the first word. */
+        __asm__ ( "bsf %1,%0" 
+                  : "=r" (set) : "r" (*p >> bit), "0" (BITS_PER_LONG) );
+        if ( set < (BITS_PER_LONG - bit) )
+            return (offset + set);
+        offset += BITS_PER_LONG - bit;
+        p++;
+    }
+
+    if ( offset >= size )
+        return size;
+
+    /* Search remaining full words for a bit. */
+    set = __find_first_bit(p, size - offset);
+    return (offset + set);
+}
+
+unsigned long __find_first_zero_bit(
+    const unsigned long *addr, unsigned long size)
+{
+    unsigned long d0, d1, d2, res;
+
+    __asm__ (
+        "   xor %%edx,%%edx\n\t" /* also ensures ZF==1 if size==0 */
+        "   repe; scas"__OS"\n\t"
+        "   je 1f\n\t"
+        "   lea -"STR(BITS_PER_LONG/8)"(%2),%2\n\t"
+        "   xor (%2),%3\n\t"
+        "   bsf %3,%0\n"
+        "1: sub %6,%2\n\t"
+        "   shl $3,%2\n\t"
+        "   add %2,%0"
+        : "=&d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+        : "1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG),
+          "2" (addr), "b" (addr), "3" (-1L) : "memory" );
+
+    return res;
+}
+
+unsigned long __find_next_zero_bit(
+    const unsigned long *addr, unsigned long size, unsigned long offset)
+{
+    const unsigned long *p = addr + (offset / BITS_PER_LONG);
+    unsigned long set, bit = offset & (BITS_PER_LONG - 1);
+
+    ASSERT(offset < size);
+
+    if ( bit != 0 )
+    {
+        /* Look for zero in the first word. */
+        __asm__ ( "bsf %1,%0" : "=r" (set) : "r" (~(*p >> bit)) );
+        if ( set < (BITS_PER_LONG - bit) )
+            return (offset + set);
+        offset += BITS_PER_LONG - bit;
+        p++;
+    }
+
+    if ( offset >= size )
+        return size;
+
+    /* Search remaining full words for a zero. */
+    set = __find_first_zero_bit(p, size - offset);
+    return (offset + set);
+}
index f0245d48820a975670876251534df7f353b28cd1..8c0a42870370b630f11098837b52af2fbb062127 100644 (file)
@@ -248,45 +248,22 @@ static __inline__ int variable_test_bit(int nr, volatile void * addr)
  constant_test_bit((nr),(addr)) : \
  variable_test_bit((nr),(addr)))
 
-/**
- * find_first_zero_bit - find the first zero bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit-number of the first zero bit, not the number of the byte
- * containing a bit.
- */
-static inline long find_first_zero_bit(
-    const unsigned long *addr, unsigned size)
+extern unsigned long __find_first_bit(
+    const unsigned long *addr, unsigned long size);
+extern unsigned long __find_next_bit(
+    const unsigned long *addr, unsigned long size, unsigned long offset);
+extern unsigned long __find_first_zero_bit(
+    const unsigned long *addr, unsigned long size);
+extern unsigned long __find_next_zero_bit(
+    const unsigned long *addr, unsigned long size, unsigned long offset);
+
+/* return index of first bit set in val or BITS_PER_LONG when no bit is set */
+static inline unsigned long __scanbit(unsigned long val)
 {
-       long d0, d1, d2;
-       long res;
-
-       __asm__ __volatile__(
-               "mov $-1,%%"__OP"ax\n\t"
-               "xor %%edx,%%edx\n\t"
-               "repe; scas"__OS"\n\t"
-               "je 1f\n\t"
-               "lea -"STR(BITS_PER_LONG/8)"(%%"__OP"di),%%"__OP"di\n\t"
-               "xor (%%"__OP"di),%%"__OP"ax\n\t"
-               "bsf %%"__OP"ax,%%"__OP"dx\n"
-               "1:\tsub %%"__OP"bx,%%"__OP"di\n\t"
-               "shl $3,%%"__OP"di\n\t"
-               "add %%"__OP"di,%%"__OP"dx"
-               :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
-               :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG),
-                "2" (addr), "b" (addr) : "memory");
-       return res;
+       __asm__ ( "bsf %1,%0" : "=r" (val) : "r" (val), "0" (BITS_PER_LONG) );
+       return val;
 }
 
-/**
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-long find_next_zero_bit(const unsigned long *addr, int size, int offset);
-
 /**
  * find_first_bit - find the first set bit in a memory region
  * @addr: The address to start the search at
@@ -295,26 +272,10 @@ long find_next_zero_bit(const unsigned long *addr, int size, int offset);
  * Returns the bit-number of the first set bit, not the number of the byte
  * containing a bit.
  */
-static inline long find_first_bit(
-    const unsigned long *addr, unsigned size)
-{
-       long d0, d1;
-       long res;
-
-       __asm__ __volatile__(
-               "xor %%eax,%%eax\n\t"
-               "repe; scas"__OS"\n\t"
-               "je 1f\n\t"
-               "lea -"STR(BITS_PER_LONG/8)"(%%"__OP"di),%%"__OP"di\n\t"
-               "bsf (%%"__OP"di),%%"__OP"ax\n"
-               "1:\tsub %%"__OP"bx,%%"__OP"di\n\t"
-               "shl $3,%%"__OP"di\n\t"
-               "add %%"__OP"di,%%"__OP"ax"
-               :"=a" (res), "=&c" (d0), "=&D" (d1)
-               :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG),
-                "2" (addr), "b" (addr) : "memory");
-       return res;
-}
+#define find_first_bit(addr,size) \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
+  (__scanbit(*(unsigned long *)addr)) : \
+  __find_first_bit(addr,size)))
 
 /**
  * find_next_bit - find the first set bit in a memory region
@@ -322,45 +283,46 @@ static inline long find_first_bit(
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-long find_next_bit(const unsigned long *addr, int size, int offset);
-
-/* return index of first bet set in val or BITS_PER_LONG when no bit is set */
-static inline unsigned long __scanbit(unsigned long val)
-{
-       asm("bsf %1,%0" : "=&r" (val) : "r" (val), "0" (BITS_PER_LONG));
-       return val;
-}
-
-#define find_first_bit(addr,size) \
-((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
-  (__scanbit(*(unsigned long *)addr)) : \
-  find_first_bit(addr,size)))
-
 #define find_next_bit(addr,size,off) \
 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   ((off) + (__scanbit((*(unsigned long *)addr) >> (off)))) : \
-  find_next_bit(addr,size,off)))
+  __find_next_bit(addr,size,off)))
 
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
 #define find_first_zero_bit(addr,size) \
 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   (__scanbit(~*(unsigned long *)addr)) : \
-  find_first_zero_bit(addr,size)))
+  __find_first_zero_bit(addr,size)))
 
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
 #define find_next_zero_bit(addr,size,off) \
 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off))))) : \
-  find_next_zero_bit(addr,size,off)))
+  __find_next_zero_bit(addr,size,off)))
 
 
-/*
- * Return index of first non-zero bit in @word (counting l.s.b. as 0).
- * If no bits are set (@word == 0) then the result is undefined.
+/**
+ * find_first_set_bit - find the first set bit in @word
+ * @word: the word to search
+ * 
+ * Returns the bit-number of the first set bit. If no bits are set then the
+ * result is undefined.
  */
 static __inline__ unsigned long find_first_set_bit(unsigned long word)
 {
-       __asm__("bsf %1,%0"
-               :"=r" (word)
-               :"r" (word));
+       __asm__ ( "bsf %1,%0" : "=r" (word) : "r" (word) );
        return word;
 }
 
@@ -370,23 +332,9 @@ static __inline__ unsigned long find_first_set_bit(unsigned long word)
  *
  * The Hamming Weight of a number is the total number of bits set in it.
  */
-
 #define hweight64(x) generic_hweight64(x)
 #define hweight32(x) generic_hweight32(x)
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
 
-#define ext2_set_bit                 __test_and_set_bit
-#define ext2_clear_bit               __test_and_clear_bit
-#define ext2_test_bit                test_bit
-#define ext2_find_first_zero_bit     find_first_zero_bit
-#define ext2_find_next_zero_bit      find_next_zero_bit
-
-/* Bitmap functions for the minix filesystem.  */
-#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) __set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr) test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
-
 #endif /* _X86_BITOPS_H */